package com.ermace.robo.jumper.game.Player;

//import be.kuleuven.cs.som.annotate.*;

/**
 *
 * @author Eric de Potter de ten Broeck
 *
 * @version 1.0
 */
//@Value
public class Position {

	/**
	 *
	 * @param x
	 * @param y
	 *
	 * @post   | new.getX() == x
	 * 		   | new.getY() == y
	 */
	public Position(double x, double y) {
		this.x = x;
		this.y = y;
	}
	
	private final double x;

//	@Basic @Immutable
	public double getX() {
		return x;
	}

	private final double y;

//	@Basic @Immutable
	public double getY() {
		return y;
	}

	/**
	 *
	 * @param pos
	 *
	 * @return | result == new Position(getX() + pos.getX(), getY() + pos.getY())
	 * @throws NullPointerException
	 * 		   | pos == null
	 */
	public Position add(Position pos) throws NullPointerException {
		return new Position(getX() + pos.getX(), getY() + pos.getY());
	}

	/**
	 *
	 * @param pos
	 *
	 * @return | result == new Position(getX() - pos.getX(), getY() - pos.getY())
	 * @throws NullPointerException
	 * 		   | pos == null
	 */
	public Position subtract(Position pos) throws NullPointerException {
		return new Position(getX() - pos.getX(), getY() - pos.getY());
	}

	/**
	 * Geeft de afstand van deze positie naar de gegeven positie terug.
	 *
	 * @param  pos
	 * 		   De gegeven positie.
	 *
	 * @return De afstand van deze positie naar de gegeven positie.
	 * 		   | Let x = Math.abs(pos.getX() - this.getX()) &&
	 * 		   |	 y = Math.abs(pos.getY() - this.getY()) In
	 * 		   | 	result == Math.sqrt(x*x + y*y) 
	 * @throws NullPointerException
	 * 		   | pos == null
	 */
	public double getDistanceTo(Position pos) throws NullPointerException {
		double distanceX = Math.abs(pos.getX() - this.getX());
		double distanceY = Math.abs(pos.getY() - this.getY());
		return  Math.sqrt(distanceX*distanceX + distanceY*distanceY);
	}

	/**
	 *
	 * @param pos
	 *
	 * @return | If (object != null && this.getClass() == object.getClass()) Then
	 * 		   |	result == (this.getX() == ((Position)object).getX()) &&
	 * 		   |				(this.getY() == ((Position)object).getY())
	 *		   | Else Then
	 *		   | 	result == false
	 */
	@Override
	public boolean equals(Object object) {
		if (object != null && this.getClass() == object.getClass())
			return (this.getX() == ((Position)object).getX()) && (this.getY() == ((Position)object).getY());
		return false;
	}

	/**
	 *
	 * 
	 */
	@Override //@Immutable
	public int hashCode() {
		if (this.equals(new Position(0, 0)))
			return 0;

		double angle = Math.atan2(this.getY(),this.getX());
		angle = (2*Math.PI + angle % 2*Math.PI) % 2*Math.PI;
		
		return (int)(( (getX() + getY()) +
				Integer.MAX_VALUE *
						(angle - Math.PI) / (Math.PI/2) ) % Integer.MAX_VALUE);
	}

	/**
	 *
	 * @return | result == "(" + getX() + ", " + getY() + ")"
	 */
	@Override //@Immutable
	public String toString() {
		return "(" + getX() + ", " + getY() + ")";
	}

}